package filter

import (
	// "fmt"
	"strconv"

	"gitee.com/kobeyyf/apibox/handler"
)

type Params struct {
	paramFilters map[string][]Filter

	c *handler.Context
}

func NewParams(c *handler.Context) *Params {
	return &Params{
		c: c,

		paramFilters: make(map[string][]Filter, 3),
	}
}

func (filter *Params) AddParam(key, value string) {
	filter.c.Request.Form.Add(key, value)
}

func (filter *Params) SetParam(key, value string) {
	filter.c.Request.Form.Set(key, value)
}

func (filter *Params) DelParam(key string) {
	filter.c.Request.Form.Del(key)
}

func (filter *Params) Add(paramName string, filterFunc ...Filter) {
	filter.paramFilters[paramName] = filterFunc
}

func (filter *Params) Parse() (apiError *handler.Response) {
	if err := filter.c.Parse(); err != nil {
		return handler.NewErrorResponseWith400(handler.ErrorCode_UnknownError, "UnknownError")
	}

	for paramName, filters := range filter.paramFilters {
		for _, filterFunc := range filters {
			if apiError = filterFunc.Handler(filter.c, paramName); apiError != nil {
				return apiError
			}
		}
	}
	return nil
}

func (params *Params) Has(name string) bool {
	_, has := params.c.Request.Form[name]
	return has
}

func (params *Params) GetString(name string) string {
	return params.c.Request.Form.Get(name)
}
func (params *Params) GetStringArray(name string) []string {
	return params.c.Request.Form[name]
}

func (params *Params) GetInt(name string) int {
	a := params.c.Request.Form.Get(name)
	value, _ := strconv.Atoi(a)
	return value

}

func (params *Params) GetInt64(name string) int64 {
	a := params.c.Request.Form.Get(name)
	value, _ := strconv.ParseInt(a, 10, 64)
	return value
}

func (params *Params) GetUint32(name string) uint32 {
	a := params.c.Request.Form.Get(name)
	value, _ := strconv.ParseUint(a, 10, 32)

	return uint32(value)
}

func (params *Params) GetUint64(name string) uint64 {
	a := params.c.Request.Form.Get(name)
	value, _ := strconv.ParseUint(a, 10, 64)
	return value
}

func (params *Params) GetUint64Set(name string) []uint64 {
	values, has := params.c.Request.Form[name]
	if !has {
		return nil
	}
	out := make([]uint64, len(values))
	for i, value := range values {
		out[i], _ = strconv.ParseUint(value, 10, 64)
	}
	return out
}

func (params *Params) GetUint32Set(name string) []uint32 {
	values, has := params.c.Request.Form[name]
	if !has {
		return nil
	}
	out := make([]uint32, len(values))
	for i, value := range values {
		tmp, _ := strconv.ParseUint(value, 10, 32)
		out[i] = uint32(tmp)
	}
	return out
}

func (params *Params) GetInt32Set(name string) []int32 {
	values, has := params.c.Request.Form[name]
	if !has {
		return nil
	}
	out := make([]int32, len(values))
	for i, value := range values {
		tmp, _ := strconv.ParseInt(value, 10, 32)
		out[i] = int32(tmp)
	}
	return out
}

func (params *Params) GetStringSet(name string) []string {
	values, _ := params.c.Request.Form[name]
	return values
}

func (params *Params) GetBool(name string) bool {
	return params.c.Request.Form.Get(name) == "true"
}
